package com.xbsg.protocol.xf.server;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xbsg.protocol.rabbitmq.MqttGateway;
import com.xbsg.protocol.xf.RS485Util;
import com.xbsg.protocol.xf.entiy.FireUploadData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import static com.xbsg.protocol.xf.server.SocketPool.*;

@Slf4j
public class SocketHandler {
    /**
     * 将连接的Socket注册到Socket池中
     * @param socket , MqttGateway mqttGateway
     * @return
     */
    public static ClientSocket register(Socket socket){
        ClientSocket clientSocket = new ClientSocket();
        clientSocket.setSocket(socket);
        //clientSocket.setMqttGateway(mqttGateway);
        try {
            clientSocket.setInputStream(new DataInputStream(socket.getInputStream()));
            clientSocket.setOutputStream(new DataOutputStream(socket.getOutputStream()));
            byte[] bytes = new byte[1024];
            clientSocket.getInputStream().read(bytes);
            //clientSocket.setKey(new String(bytes, "utf-8"));
            add(clientSocket);
            return clientSocket;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 向指定客户端发送信息
     * @param clientSocket
     * @param message
     */
    public static void sendMessage(ClientSocket clientSocket, String message){
        try {
            log.info("发送消息到客户端  : >>>>>" + message);
            clientSocket.getOutputStream().write(message.getBytes("utf-8"));
            //clientSocket.getOutputStream().writeUTF(message);
        } catch (IOException e) {
            log.error("发送信息异常：{}", e);
            close(clientSocket);
        }
    }

    /**
     * 获取指定客户端的上传信息
     * @param clientSocket
     * @return
     */
    public static void onMessage(ClientSocket clientSocket){
        byte[] keyByte = new byte[1024];
        byte[] msgByte = new byte[1];
        try {
            // 第一次先发送序列号
            if(StringUtils.isEmpty(clientSocket.getKey())) {
                clientSocket.getInputStream().read(keyByte);
                clientSocket.setKey(new String(keyByte, "UTF-8"));
                //return clientSocket.getKey();
                // 以后发送数据
            }else {
                String info = "";
                while (true) {
                    if (clientSocket.getInputStream().available() > 0) {
                        clientSocket.getInputStream().read(msgByte);
                        String tempStr = HexEcodeUtil.ByteArrayToHexStr(msgByte);
                        info += tempStr;
                        //已经读完
                        if (clientSocket.getInputStream().available() == 0) {
                            //重置,不然每次收到的数据都会累加起来
                            clientSocket.setMessage(info);
                            break;
                        }
                    }
                }
                //return clientSocket.getMessage();
            }
        } catch (IOException e) {
            e.printStackTrace();
            close(clientSocket);
        }
        //return null;
    }

    /***
     * 解析消防协议 ,返回json字符串
     * @param hexMessage
     * @return
     */
    public static void parseMessage(ClientSocket clientSocket){
        String hexMessage = clientSocket.getMessage();
        String result = null;
        result = parseMessage(hexMessage);
        if(result != null && !result.equals("心跳信息")){
            //运行信息，操作信息，发送消息队列
            clientSocket.sendJSONByMQTT(result);
        }

        clientSocket.setContent(result);
    }

    public static FireUploadData parseMessage2Entity(String hexMessage){
        FireUploadData fireUploadData = RS485Util.getFireUploadData(hexMessage);
        return fireUploadData;
    }

    public static String parseMessage(String hexMessage){
        String result = null;
        FireUploadData fireUploadData = RS485Util.getFireUploadData(hexMessage);
        if(fireUploadData.getAppDataFlag().equals("2")|| fireUploadData.getAppDataFlag().equals("4")){
            ObjectMapper mapper = new ObjectMapper();
            try {
                result = mapper.writeValueAsString(fireUploadData);
                System.out.println("上传信息");

            } catch (JsonProcessingException e) {
                e.printStackTrace();

            }
        }else{
            result ="心跳信息";
        }
        return result;
    }

/*    private static MqttGateway mqttGateway = null;
    private static void sendJSONByMQTT(String message){
        //get bean
        if(mqttGateway == null){
            if(XfApplication.ac == null){
                System.out.println("ac is null");
            }
            mqttGateway = XfApplication.ac.getBean(MqttGateway.class);
        }
        mqttGateway.sendToMqtt(message,MQTTConfig.MQTT_TOPIC);
    }*/

    /**
     * 指定Socket资源回收
     * @param clientSocket
     */
    public static void close(ClientSocket clientSocket){
        log.info("进行资源回收");
        if (clientSocket != null){
            log.info("开始回收socket相关资源，其Key为{}", clientSocket.getKey());
            remove(clientSocket.getKey());
            Socket socket = clientSocket.getSocket();
            try {
                socket.shutdownInput();
                socket.shutdownOutput();
            } catch (IOException e) {
                log.error("关闭输入输出流异常，{}", e);
            }finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    log.error("关闭socket异常{}", e);
                }
            }
        }
    }


    /**
     * 发送数据包，判断数据连接状态
     * @param clientSocket
     * @return
     */
    public static boolean isSocketClosed(ClientSocket clientSocket){
        try {
            clientSocket.getSocket().sendUrgentData(1);
            return false;
        } catch (IOException e) {
            return true;
        }
    }

}
